#include <iostream>
#include <fstream>
#include <map>

struct FileHeaderStruct {
    size_t size;
};

struct FileDataStruct {
    int32_t key;
    char typeString[32];
    int32_t type;
    int32_t zIndex;
    struct Layout {
        int32_t x;
        int32_t y;
        int32_t w;
        int32_t h;
    } layout;
    enum class PositionType : int {
        RELATIVE,
        STATIC,
        FIXED,
    } position;
};

std::ostream &operator <<(std::ostream &os, const enum FileDataStruct::PositionType &position)
{
    switch (position) {
        case FileDataStruct::PositionType::RELATIVE:
            os << "relative";
            break;
        case FileDataStruct::PositionType::STATIC:
            os << "static";
            break;
        case FileDataStruct::PositionType::FIXED:
            os << "fixed";
            break;
        default:
            os << "unknown enum value(" << static_cast<int>(position) << ")";
            break;
    };
    return os;
}

std::map<int32_t, FileDataStruct> datas;

void Read()
{
    std::ifstream ifs("file.bin", std::ifstream::in | std::ifstream::binary);
    struct FileHeaderStruct header;
    ifs.read((char *)&header, sizeof(header));
    struct FileDataStruct data = {};
    for (int32_t i = 0; i < header.size; i++) {
        ifs.read((char *)&data, sizeof(data));
        datas[data.key] = data;
    }
}

void Write(int argc, const char **argv)
{
    std::ofstream ofs("file.bin", std::ofstream::out | std::ofstream::binary);
    struct FileHeaderStruct header = { datas.size() };
    ofs.write(reinterpret_cast<const char *>(&header), sizeof(header));
    for (const auto &[key, data] : datas) {
        ofs.write(reinterpret_cast<const char *>(&data), sizeof(data));
    }
    ofs.close();
}

int main(int argc, const char **argv)
{
    if (argc != 1) {
        Read();
        for (const auto &[key, data] : datas) {
            std::cout << data.typeString << " " << data.layout.x << " " << data.position << std::endl;
        }
    } else {
        datas[0] = {0, "0", 0, 0, {0, 0, 0, 0}, FileDataStruct::PositionType::STATIC};
        datas[1] = {1, "1", 1, 1, {1, 1, 1, 1}, FileDataStruct::PositionType::FIXED};
        datas[2] = {2, "2", 2, 2, {2, 2, 2, 2}, static_cast<enum FileDataStruct::PositionType>(-1)};
        Write(argc, argv);
    }
    return 0;
}
